<script setup>
import { onMounted, ref } from 'vue';
import axios from 'axios'
import bwPowerSet from './power-set';

// 商品数据
const goods = ref({})
let pathMap = {}
const getGoods = async () => {
  const res = await axios.get('http://pcapi-xiaotuxian-front-devtest.itheima.net/goods?id=1369155859933827074')
  goods.value = res.data.result

  // 数据加载完成后，调用getPathMap
  pathMap = getPathMap(goods.value)
  console.log(pathMap);

  // 初始化更新按钮状态
  initDisabledState(goods.value.specs, pathMap)
}

onMounted(() => getGoods())


// 选中和取消选中实现
const changeSku = (item, val) => {
  // console.log(item);
  // console.log(val);
  // console.log(val.selected);
  if (val.disabled) return

  // 两种情况： 1. 点击的是未选中，把同一个规格的其它取消选中
  // 2. 当前点击项选中，如果点击的是已选中目标，那么直接取消
  if (val.selected) {
    val.selected = false
  } else {
    item.values.forEach(valIem => valIem.selected = false)
    val.selected = true
  }

  // 测试
  // const arr = getSelectedValues(goods.value.specs)
  // console.log(arr);

  // 点击按钮时更新
  updateDisabledState(goods.value.specs, pathMap)

  // 产出SKU对象数据
  const index = getSelectedValues(goods.value.specs).findIndex(item => item === undefined)
  if (index > -1) {
    console.log('找到了，信息不完整');
  } else {
    console.log('没有找到，信息完整，可以产出');
    const key = getSelectedValues(goods.value.specs).join('-')
    const skuIds = pathMap[key]
    // console.log(skuIds);
    // 以skuId作为匹配项去goods.value.skus数组中找
    const skuObj = goods.value.skus.find(item => item.id === skuIds[0])
    console.log('sku对象为：', skuObj);
    
    
    
  }

}


// 生成有效路径字典对象
const getPathMap = (goods) => {
  const pathMap = {}
  // 1. 根据skus字段生成有效的sku数组
  const effectiveSkus = goods.skus.filter(sku => sku.inventory > 0)
  // console.log(effectiveSkus);
  // 2.根据有效的sku使用算法（子集算法） 例如: [1, 2] => [[1],[2],[1,2]]
  effectiveSkus.forEach(sku => {
    // 2.1 获取匹配的valueName组成的数组
    const selectedValArr = sku.specs.map(val => val.valueName)
    // console.log(selectedValArr);  // ['黑色', '20cm', '中国']
    // 2.2 使用算法获取子集
    const valueArrPowerSet = bwPowerSet(selectedValArr)
    // console.log(valueArrPowerSet);
    // 3. 把得到的子集 生成最终的路径字典对象
    valueArrPowerSet.forEach(arr => {
      // 初始化key 数组join => 字符串 对象的key
      const key = arr.join('-')
      // console.log(key);
      // 如果已经存在当前key了，就往数组中直接添加skuId,如果不存在key， 直接做赋值
      if (pathMap[key]) {
        pathMap[key].push(sku.id)
      }
      else {
        pathMap[key] = [sku.id]
      }
    })
  })
  return pathMap

}

// 定义初始化函数，将每一个目标都设置为可选择
// specs: 商品源数据  pathMap:路径字典
const initDisabledState = (specs, pathMap) => {
  // 约定：每一个按钮的状态由自身的disabled进行控制
  specs.forEach(item => {
    item.values.forEach(val => {
      // 路径字典中查找是否有数据，有-可以点击  没有-禁用
      val.disabled = !pathMap[val.name]
    })
  })
}

const updateDisabledState = (specs, pathMap) => {
  // 每一个按钮的状态由自身的disabled进行控制
  specs.forEach((item, i) => {
    // console.log('item:', item);
    // console.log('i:', i)
    // 按照顺序得到规格选中项的数组['蓝色, '20cm', undefined']
    const selectedValues = getSelectedValues(specs)
    // console.log(selectedValues);
    
    item.values.forEach(val => {
      if (val.selected) return
      const _selectedValues = [...selectedValues]
      
      // 把name字段的值填充到相应位置
      _selectedValues[i] = val.name
      // 过滤掉undefined项使用join方法形成一个有效的key
      // console.log(_selectedValues);
      
      const key = _selectedValues.filter(value => value).join('-')
      // console.log(key);
      
      // 路径字典中查找是否有数据，有-可以点击，没有禁用
      val.disabled = !pathMap[key]
    })
    
  })
}

// 获取选中匹配数组['黑色', undefined, undefined]
const getSelectedValues = (specs) => {
  const arr = []
  specs.forEach(spec => {
    const selectedVal = spec.values.find(value => value.selected)
    arr.push(selectedVal ? selectedVal.name : undefined)
  })

  return arr
}


</script>

<template>
  <div class="goods-sku">
    <dl v-for="item in goods.specs" :key="item.id">
      <dt>{{ item.name }}</dt>
      <dd>
        <template v-for="val in item.values" :key="val.name">
          <!-- 图片类型规格 -->
          <img v-if="val.picture" :src="val.picture" :title="val.name" @click="changeSku(item, val)"
            :class="{ selected: val.selected, disabled: val.disabled }">
          <!-- 文字类型规格 -->
          <span v-else @click="changeSku(item, val)" :class="{ selected: val.selected, disabled: val.disabled }">
            {{ val.name }}
          </span>
        </template>
      </dd>
    </dl>
  </div>
</template>

<style scoped lang='scss'>
// 定义可复用的样式
@mixin sku-state-mixin {
  border: 1px solid #e4e4e4;
  margin-right: 10px;
  cursor: pointer;

  &.selected {
    border-color: $xtxColor;
  }

  &.disabled {
    opacity: 0.6;
    border-style: dashed;
    cursor: not-allowed;
  }
}

.goods-sku {
  padding-left: 10px;
  padding-top: 20px;

  dl {
    display: flex;
    padding-bottom: 20px;
    align-items: center;

    dt {
      width: 50px;
      color: #999;
    }

    dd {
      flex: 1;
      color: #666;

      >img {
        width: 50px;
        height: 50px;
        margin-bottom: 4px;
        @include sku-state-mixin; // 调用样式
      }

      >span {
        display: inline-block;
        height: 30px;
        line-height: 28px;
        padding: 0 20px;
        margin-bottom: 4px;
        @include sku-state-mixin()
      }
    }
  }
}
</style>
